package com.zrrd.gmall.product.service.impl;

import com.zrrd.gmall.product.service.TestService;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.client.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
public class TestServiceImpl implements TestService {

    //注入操作Redis的对象
    @Autowired
    private StringRedisTemplate redisTemplate;
    //注入Redssion的操作对象
    @Autowired
    private RedissonClient redissonClient;

    //可重入锁
    @Override
    public void testLock() throws InterruptedException {
        //定义一个key
        String skuId = "45";
        String lockKey = "lock:" + skuId;
        //创建锁
        RLock lock = redissonClient.getLock(lockKey);
        //开始上锁(最多等待100秒 上锁后10秒自动解锁 返回值：上锁是否成功)
        boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
        //判断是否上锁成功
        if (res) {
            //try开始结构来区分业务是否有异常
            try {
                //查询redis中key为num的数据
                String value = redisTemplate.opsForValue().get("num");
                //非空判断
                if (StringUtils.isBlank(value)) {
                    return;
                }
                //将value转为整数
                int num = Integer.parseInt(value);
                //将num+1重新存入到redis中
                redisTemplate.opsForValue().set("num", String.valueOf(++num));
            } catch (Exception e) {
                //打印异常信息
                System.out.println("业务发生了异常：信息是===>" + e.getMessage());
            } finally {
                //无论业务中是否发生了异常 都应该释放锁
                lock.unlock();
            }
        }
    }

    //读写锁->读操作
    @Override
    public String readLock() throws InterruptedException {
        //初始化读写锁
        RReadWriteLock readwriteLock = redissonClient.getReadWriteLock("readwriteLock");
        //获取读锁
        RLock readLock = readwriteLock.readLock();
        //上锁 10s后自动解锁
        readLock.tryLock(10, TimeUnit.SECONDS);
        //读取指定的key的数据
        String msg = redisTemplate.opsForValue().get("msg");
        //返回
        return msg;
    }

    //读写锁->写操作
    @Override
    public String writeLock() {
        //初始化读写锁
        RReadWriteLock readwriteLock = redissonClient.getReadWriteLock("readwriteLock");
        //获取写锁
        RLock writeLock = readwriteLock.writeLock();
        //上锁 10s后自动解锁
        writeLock.lock(10, TimeUnit.SECONDS);
        //写入数据
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("msg", uuid);
        //返回结果
        return "写入数据成功：" + uuid;
    }
}
